#页面父类
#封装了：针对于每个UI都需要用到的一些通用的属性、通用的UI操作
from selenium.webdriver.support.select import Select
from selenium.webdriver.common.action_chains import ActionChains
import time,os
from selenium.webdriver.common.keys import Keys

class PageBase(object):
    def __init__(self,driver,base_url):
        self.driver=driver
        self.base_url=base_url

    def find_element(self,loc):
        by=loc[0]
        value=loc[1]
        return self.driver.find_element(by,value)

    def find_elements(self,loc):
        by=loc[0]
        value=loc[1]
        return self.driver.find_elements(by,value)

    #通用的UI操作：打开某url
    def open(self,pathUrl):
        self.driver.get(self.base_url+pathUrl)

    #通用的UI操作：点击某元素loc
    def click(self,loc):
        self.find_element(loc).click()

    # 适合：文本框、密码框、多行文本框
    # 功能：给元素loc输入数据data
    def input(self,loc,data):
        ele=self.find_element(loc)
        ele.send_keys(data)

    # 适合：文本框、密码框、多行文本框
    # 功能：清空元素loc的数据
    def clear(self,loc):
        ele =self.find_element(loc)
        ele.clear()

    # 对文本框/密码框/多行文本框进行清空并输入数据：不会触发鼠标失去焦点事件
    def clearAndInput(self, loc, data,):
        ele = self.find_element(loc)
        ele.send_keys(Keys.CONTROL, 'a')
        ele.send_keys(Keys.BACK_SPACE)
        ele.send_keys(data)

    # 适合：文本框、密码框、多行文本框
    # 功能：获取用户输入的数据
    def getUserData1(self,loc):
        ele = self.find_element(loc)
        return ele.get_attribute("value")

    # 适合：单选按钮
    # 功能：选中某选项。通过你想要选中的那个选项的value属性的值来选中该选项
    def click_radio(self, attrName, attr_value):
        ele_option = self.driver.find_element_by_css_selector(
            f"input[type='radio'][name='{attrName}'][value='{attr_value}']")
        ele_option.click()

    # 适合：单选按钮
    # 功能：获取用户选中的那个选项的value属性的值。
    def getUserData2(self, attrName):
        option_value = ""
        eles_option = self.driver.find_elements_by_css_selector(f"input[type='radio'][name='{attrName}']")
        for x in eles_option:
            status = x.is_selected()
            if status:
                option_value = x.get_attribute("value")
                break
        return option_value

    # 适合：下拉列表
    # 功能：选中某选项。根据你想要选中的那个选项的文本内容来选中该选项
    def click_select(self, attrName, optionText):
        ss = Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        ss.select_by_visible_text(optionText)

    # 适合：下拉列表
    # 功能：获取用户选中的那个选项的文本内容。
    def getUserData3(self, attrName):
        ss = Select(self.driver.find_element_by_css_selector(f"select[name='{attrName}']"))
        option = ss.first_selected_option
        return option.text

    # 适合：复选框
    # 功能：选中N个选项:选中1个选项/2个选项/0个选项/
    def click_checkbox(self, attrName, target_option_values):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            value = x.get_attribute("value")
            status = x.is_selected()
            if value in target_option_values:  # 表示该选项一定要选中
                if not status:
                    x.click()
            else:  # 表示该选项一定不要选中
                if status:
                    x.click()

    # 适合：复选框
    # 功能：全选所有选项
    def quanxuan_checkbox(self, attrName):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            status = x.is_selected()
            if not status:
                x.click()

    # 适合：复选框
    # 功能：全不选。即任何选项都不选中
    def quanbuxuan_checkbox(self, attrName):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            status = x.is_selected()
            if status:
                x.click()

    # 适合：复选框
    # 功能：反选。
    def fanxuanxuan_checkbox(self, attrName):
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            x.click()

    # 适合：复选框
    # 功能：获取用户选中的这些选项的value属性的值
    def getUserData4(self, attrName):
        values = ""
        allOption = self.driver.find_elements_by_css_selector(f"input[type='checkbox'][name='{attrName}']")
        for x in allOption:
            status = x.is_selected()
            if status:
                value = x.get_attribute("value")
                values += value + ","
        return values[:-1]

    # 适合：日期控件
    # 功能：输入某日期（支持年月日，也支持年月日时分秒）
    def input_riqi(self, loc, riqi):
        ele_riqi = self.find_element(loc)
        self.driver.execute_script("arguments[0].value=arguments[1];", ele_riqi, riqi)

    # 适合：日期控件
    # 功能：获取用户输入的日期值。（支持年月日，也支持年月日时分秒）
    def getUserData5(self, loc):
        ele = self.find_element(loc)
        return ele.get_attribute("value")

    # 适合：上传文件：方法1：不通用
    # 功能：上传1个/N个文件/目录
    def uploadFileorDirs1(self, loc, filesPath):
        filePath_new = filesPath.replace(",", "\n")
        ele_file = self.find_element(loc)
        ele_file.send_keys(filePath_new)

    # 适合：上传文件：方法2：通用
    # 功能：上传1个/N个文件/目录
    def uploadFileorDirs2(self, loc, filePath):
        a = filePath.replace("/", "\\")  # "C:\A\haha.png,C:\A\heihei.jpg"
        b = a.split(",")  # ["C:\A\haha.png","C:\A\heihei.jpg"]
        filePath_new = ""
        for x in b:
            filePath_new += '"' + x + '" '

        ele_file = self.find_element(loc)
        ActionChains(self.driver).click(ele_file).perform()
        time.sleep(2)

        os.system(f'{os.getcwd()}/tools/uploadFiles.exe {filePath_new}')


    #通用的UI操作：获取某元素loc的文本内容
    def getEleText(self,loc):
        ele=self.find_element(loc)
        return ele.text.strip()

    # 获取某元素的某属性的值（并去掉首尾空格）
    def getEleAttr(self, loc, attrName):
        return self.find_element(loc).get_attribute(attrName).strip()

    # 处理JS三种弹出框
    # 获取三种JS弹出框的文本内容
    def getTextForJsTanCuKuan(self):
        return self.driver.switch_to.alert.text

    # 点击三种JS弹出框的“确定”按钮
    def acceptForJsTanCuKuan(self):
        self.driver.switch_to.alert.accept()

    # 点击三种JS弹出框的“取消”按钮
    def dismissForJsTanCuKuan(self):
        self.driver.switch_to.alert.dismiss()

    # 为JS的prompt弹出框输入文本
    def inputJsTanCuKuan(self, data):
        self.driver.switch_to.alert.send_keys(data)

    # iframe框架相关处理
    # 切换到某iframe
    def switch_iframe(self, loc_iframe):
        ele_ifame = self.find_element(loc_iframe)
        self.driver.switch_to.frame(ele_ifame)

    # 切换到主iframe
    def switch_defaultIframe(self):
        self.driver.switch_to.default_content()

    # 鼠标操作的相关处理

    # 函数功能：鼠标单击某元素loc
    def mouse_click(self, loc):
        ele = self.find_element(loc)
        ActionChains(self.driver).click(ele).perform()

    # 函数功能：鼠标双击某元素loc
    def mouse_dbclick(self, loc):
        ele = self.find_element(loc)
        ActionChains(self.driver).double_click(ele).perform()

    # 函数功能：鼠标悬停在某元素loc
    def mouse_moveToEle(self, loc):
        ele = self.find_element(loc)
        ActionChains(self.driver).move_to_element(ele).perform()

    # 函数功能：滑动垂直滚动条到最底部
    def scrollToFloor(self):
        js1 = "window.scrollTo(0,10000)"
        self.driver.execute_script(js1)

    # 网页截图
    def savePng1(self, filePath):
        self.driver.get_screenshot_as_file(filePath)

    def savePng2(self, fileName):
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")

    def savePng3(self, serviceName, key):
        fileName = serviceName + "_" + key + "_" + time.strftime("%Y%m%d%H%M%S")
        self.driver.get_screenshot_as_file("./screen/" + fileName + ".png")
        return fileName

    # 切换标签页/切换窗口
    # 形参n是第几个窗口。n从0开始.-1：最新打开窗口
    def switch_windowByIndex(self, n):
        self.driver.switch_to.window(self.driver.window_handles[n])

    # 根据窗口标题（可以给部分）来切到对应的窗口换
    def switch_windowByTitle(self, target_title):
        moren_handler = self.driver.current_window_handle
        flag = True
        allWindows = self.driver.window_handles
        for one in allWindows:
            self.driver.switch_to.window(one)
            currentTitle = self.driver.title
            if target_title in currentTitle:
                flag = False
                break
            time.sleep(1)
        if flag:
            self.driver.switch_to.window(moren_handler)

    # 根据窗口url（可以给部分）来切到对应的窗口换
    def switch_windowByUrl(self, target_url):
        moren_handler = self.driver.current_window_handle
        flag = True
        allWindows = self.driver.window_handles
        for one in allWindows:
            self.driver.switch_to.window(one)
            currentUrl = self.driver.current_url
            if target_url in currentUrl:
                flag = False
                break
            time.sleep(1)
        if flag:
            self.driver.switch_to.window(moren_handler)




